package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var count int64
	var wg sync.WaitGroup

	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			atomic.AddInt64(&count, 1)
		}()
	}

	wg.Wait()
	fmt.Println("Final count:", count)
}

/*
核心原理
atomic.AddInt64() 通过硬件级别的原子指令来确保整个"读取-修改-写入"操作是不可中断的，从而在多线程环境下保证数据的一致性。

底层实现机制
1. 硬件支持
CPU原子指令：现代CPU提供专门的原子指令，如 x86 的 LOCK XADD、LOCK INC，ARM 的 LDREX/STREX 等

内存屏障：确保指令执行顺序和内存可见性

缓存一致性协议：如 MESI 协议，确保多核CPU缓存的一致性


2. Go 语言层面的实现
在Go的运行时源码中（通常是 runtime/internal/atomic 包），AddInt64 的实现类似于：

go
// 伪代码，展示原理
func AddInt64(addr *int64, delta int64) int64 {
    for {
        old := LoadInt64(addr)          // 原子读取当前值
        new := old + delta              // 计算新值
        if CompareAndSwapInt64(addr, old, new) { // CAS操作
            return new                  // 成功则返回新值
        }
        // 如果失败（值被其他goroutine修改），重试
    }
}

3. 实际硬件指令示例
x86架构：

asm
LOCK XADD QWORD PTR [addr], delta
LOCK：总线锁前缀，确保指令的原子性

XADD：交换并相加指令

ARM架构：

asm
LDREX x0, [addr]    // 加载并独占监视
ADD x0, x0, delta   // 计算新值
STREX w1, x0, [addr] // 尝试存储，如果独占权还在
CMP w1, #0          // 检查是否成功
BNE retry           // 失败则重试
内存模型保证
atomic.AddInt64() 提供以下保证：

原子性：操作不可分割，不会被其他goroutine中断

顺序一致性：操作前后的内存访问顺序得到保证

可见性：修改结果立即对其他CPU核心可见

与传统非原子操作的对比
非原子操作（危险）：
go
count++ // 可能被分解为多个指令：
// 1. MOV count, register
// 2. ADD register, 1
// 3. MOV register, count
// 中间可能被其他goroutine中断
原子操作（安全）：
go
atomic.AddInt64(&count, 1) // 单条原子指令完成
实际应用场景
go
package main

import (
    "fmt"
    "sync"
    "sync/atomic"
    "time"
)

func main() {
    var count int64
    var wg sync.WaitGroup

    // 启动多个goroutine并发计数
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            for j := 0; j < 1000; j++ {
                // 原子操作确保线程安全
                newVal := atomic.AddInt64(&count, 1)
                if j%100 == 0 {
                    fmt.Printf("Goroutine %d: count = %d\n", id, newVal)
                }
                time.Sleep(time.Microsecond) // 模拟工作负载
            }
        }(i)
    }

    wg.Wait()
    fmt.Println("Final count:", count) // 正确输出: 100000
}
性能考虑
开销：原子操作比普通操作慢，但比互斥锁快

缓存行：避免false sharing（多个变量在同一缓存行）

忙等待：CAS操作在竞争激烈时可能多次重试

最佳实践
简单计数：优先使用 atomic

复杂操作：考虑使用 sync.Mutex

内存对齐：确保原子变量正确对齐以提高性能

避免过度使用：只在必要时使用原子操作

go
// 确保内存对齐的最佳实践
type Counter struct {
    count int64
    _     [7]int64 // 填充，确保独占缓存行（64字节）
}

func main() {
    var counter Counter
    atomic.AddInt64(&counter.count, 1)
}
总结
atomic.AddInt64(&count, 1) 的原理是：

通过硬件提供的原子指令实现

确保"读取-修改-写入"操作的不可中断性

提供内存顺序和可见性保证

比互斥锁更轻量，适合简单的原子操作

这种机制使得在多核处理器环境下实现无锁的线程安全计数成为可能。


*/
